from socket import *
from threading import *
import thread
import threading

import Logger
import ActionHandler


class Comms (Thread):

    BUFSIZE = 1024

    def __init__ (self, optdb):
        Thread.__init__(self)
        self.server_addr = (optdb['host'],optdb['port'])
        self.optdb = optdb
        self._stop = 0

    def run(self):
        #Create the socket
        serversock = socket(AF_INET, SOCK_STREAM)
        serversock.settimeout(1)
        serversock.bind(self.server_addr)
        serversock.listen(2)
        
        Logger.printLog('Server socket up and listening on: '+ self.server_addr[0]+':'+str(self.server_addr[1]))
        #create handler threads for each client connection
        while not self._stop:
            #Get a connection, spawn a client socket
            try:
                clientsock, client_addr = serversock.accept()
            except:
                #Assume this is a timeout event
                continue
            Logger.printLog('Connected with: ' + client_addr[0]+':'+str(client_addr[1]))
            thread.start_new_thread(self.conn_handler, (clientsock, client_addr))
        serversock.close()
        
    def stop(self):
        self._stop = 1

    """
    Listens for commands from the client. Will close if no activity, empty command or 'close' command.  
    """
    def conn_handler(self,clientsock, client_addr):
        
        #Set timeout on clientsock
        clientsock.settimeout(40)
        
        while 1:
            try:
                data = clientsock.recv(self.BUFSIZE)
            except:
                #Probably a timeout
                Logger.printLog('Timeout waiting for cmd from client')
                break
            if not data:
                Logger.printLog('Nothing sent by client: ' + client_addr[0]+':'+str(client_addr[1]))
                break
            if data == 'close':
                Logger.printLog('Client requests close...')
                break
        
            #echo the command
            try:
                clientsock.send(data+'\n')
            except:
                Logger.printLog('Error when echoing to client: ' + client_addr[0]+':'+str(client_addr[1]))
                break
            
            #Try and action the cmd.
            ActionHandler.clientCommand(data, self.optdb)
            
        try:
            clientsock.send("close\n")
        except:
            Logger.printLog('Error when sending close to client: ' + client_addr[0]+':'+str(client_addr[1]))
        clientsock.close()
        Logger.printLog('Disconnected  ' + client_addr[0]+':'+str(client_addr[1]))





